﻿using Cordyceps.Elasticsearch.Tool.Options;
using Elastic.Clients.Elasticsearch;
using Elastic.Clients.Elasticsearch.IndexManagement;

namespace Cordyceps.Elasticsearch.Tool.Services;

/// <summary>
/// Elasticsearch服务接口
/// </summary>
public interface IElasticsearchService
{
    /// <summary>
    /// 获取Elasticsearch客户端实例
    /// </summary>
    ElasticsearchClient Client { get; }
    
    /// <summary>
    /// 索引单个文档
    /// </summary>
    /// <typeparam name="T">文档类型</typeparam>
    /// <param name="document">文档对象</param>
    /// <param name="indexName">索引名称（可选，使用默认索引如果为空）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>索引响应</returns>
    Task<IndexResponse> IndexDocumentAsync<T>(T document, string? indexName = null, CancellationToken cancellationToken = default) where T : class;
    
    /// <summary>
    /// 批量索引文档
    /// </summary>
    /// <typeparam name="T">文档类型</typeparam>
    /// <param name="documents">文档集合</param>
    /// <param name="indexName">索引名称（可选，使用默认索引如果为空）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>批量响应</returns>
    Task<BulkResponse> BulkIndexDocumentsAsync<T>(IEnumerable<T> documents, string? indexName = null, CancellationToken cancellationToken = default) where T : class;
    
    /// <summary>
    /// 根据ID获取文档
    /// </summary>
    /// <typeparam name="T">文档类型</typeparam>
    /// <param name="id">文档ID</param>
    /// <param name="indexName">索引名称（可选，使用默认索引如果为空）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>文档对象或null（如果不存在）</returns>
    Task<T?> GetDocumentAsync<T>(string id, string? indexName = null, CancellationToken cancellationToken = default) where T : class;
    
    /// <summary>
    /// 搜索文档
    /// </summary>
    /// <typeparam name="T">文档类型</typeparam>
    /// <param name="searchDescriptor">搜索描述器</param>
    /// <param name="indexName">索引名称（可选，使用默认索引如果为空）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>搜索响应</returns>
    Task<SearchResponse<T>> SearchAsync<T>(Action<SearchRequestDescriptor<T>> searchDescriptor, string? indexName = null, CancellationToken cancellationToken = default) where T : class;
    
    /// <summary>
    /// 删除文档
    /// </summary>
    /// <typeparam name="T">文档类型</typeparam>
    /// <param name="id">文档ID</param>
    /// <param name="indexName">索引名称（可选，使用默认索引如果为空）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>删除响应</returns>
    Task<DeleteResponse> DeleteDocumentAsync<T>(string id, string? indexName = null, CancellationToken cancellationToken = default) where T : class;
    
    /// <summary>
    /// 创建索引
    /// </summary>
    /// <typeparam name="T">文档类型</typeparam>
    /// <param name="indexDefinition">索引定义</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>创建索引响应</returns>
    Task<CreateIndexResponse> CreateIndexAsync<T>(IndexDefinition<T> indexDefinition, CancellationToken cancellationToken = default) where T : class;
    
    /// <summary>
    /// 删除索引
    /// </summary>
    /// <param name="indexName">索引名称</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>删除索引响应</returns>
    Task<DeleteIndexResponse> DeleteIndexAsync(string indexName, CancellationToken cancellationToken = default);
    
    /// <summary>
    /// 检查索引是否存在
    /// </summary>
    /// <param name="indexName">索引名称</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否存在</returns>
    Task<bool> IndexExistsAsync(string indexName, CancellationToken cancellationToken = default);
}